package org.eclipse.epsilon.emc.rdbms.core.unitesting.blackbox;

	import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;

import java.sql.SQLException;

import org.eclipse.epsilon.emc.rdbms.core.imodel.DBReflexiveModel;
import org.eclipse.epsilon.emc.rdbms.core.imodel.DBReflexiveModelElement;
import org.eclipse.epsilon.emc.rdbms.core.persistancebroker.PersistanceBroker;
import org.eclipse.epsilon.emc.rdbms.core.persistancemechanism.H2Database;
import org.eclipse.epsilon.emc.rdbms.core.persistancemechanism.RelationalDatabase;
import org.eclipse.epsilon.eol.exceptions.EolRuntimeException;
import org.eclipse.epsilon.eol.exceptions.models.EolEnumerationValueNotFoundException;
import org.eclipse.epsilon.eol.exceptions.models.EolModelElementTypeNotFoundException;
import org.eclipse.epsilon.eol.exceptions.models.EolModelLoadingException;
import org.eclipse.epsilon.eol.exceptions.models.EolNotInstantiableModelElementTypeException;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;



	public class JUnit_BlackBox_DBReflexiveModel {

	PersistanceBroker  pb = new PersistanceBroker();
	RelationalDatabase Connection = null;
	DBReflexiveModel rModel = new DBReflexiveModel();  //Create a new model.
		
	@Before 
	public void pre_test ()
	{
	Connection = pb.connectTo();
	Connection.db_setup("C:\\config.sql");	
	rModel.setName("epsilon"); //Set the Model Name
	}
		

	@Test
	public void DBReflexiveModel_load() throws EolModelLoadingException
	{
	//We dont expect this do do anything.
	rModel.load();
	}

	@Test
	public void DBReflexiveModel_getEnumerationValue() throws EolEnumerationValueNotFoundException
	{
	//We dont expect this to do anything so we pass in null.			
	assertEquals("This should return null", null, rModel.getEnumerationValue(null, null));
	assertEquals("This should return null", null, rModel.getEnumerationValue(new String(), new String()));
	}

	@Test
	public void DBReflexiveModel_allContents() 
	{
	assertEquals("This should return null", null, rModel.allContents());	
	}

	@Test
	public void DBReflexiveModel_getAllOfType() throws EolModelElementTypeNotFoundException,SQLException
	{
		//This only accepts string values so only need to test strings and nulls
		assertEquals("Check size of Type that exists",5,rModel.getAllOfType("CUSTOMER").size());
	}


	@Ignore
	public void DBReflexiveModel_getTypeOf()
	{
		//Not implemented
	}

	@Test
	public void DBReflexiveModel_getTypeNameOf()
	{
	assertEquals("Should return Customer","CUSTOMER",rModel.getTypeNameOf(new DBReflexiveModelElement("CUSTOMER")));
	assertEquals("Should return null",null,rModel.getTypeNameOf(new DBReflexiveModelElement(null)));
	}

	@Test
	public void DBReflexiveModel_createInstance()  
	{
		Object element = new Object();
		try 
		{
		element = rModel.createInstance("CUSTOMER");
		assertEquals("This shold return a customer Element","CUSTOMER",((DBReflexiveModelElement) element).getType());
		} 
		catch (EolModelElementTypeNotFoundException e) 
		{
			e.printStackTrace();
		} catch (EolNotInstantiableModelElementTypeException e) 
		{
			e.printStackTrace();
		}
	}
	
@Test
public void DBReflexiveModel_getElementById()
{
	assertEquals("This should return null",null,rModel.getElementById("test"));
	assertEquals("This should return null",null,rModel.getElementById(null));	
}

@Test
public void DBReflexiveModel_getElementId()
{
	Object element = null;
	try 
	{	
		element = rModel.createInstance("CUSTOMER");
	} 
	catch (EolModelElementTypeNotFoundException e) 
	{
		e.printStackTrace();
	} catch (EolNotInstantiableModelElementTypeException e) 
	{
		e.printStackTrace();
	}
	assertEquals("This should return null","5",rModel.getElementId((DBReflexiveModelElement) element));
}

@Ignore
public void DBReflexiveModel_setElementId()
{
//Not implemented so nothing to return.
}

@Test public void DBReflexiveModelElement_deleteElement()
{	
	try {
		int count = rModel.getAllOfType("CUSTOMER").size();
		Object element = rModel.createInstance("CUSTOMER");
		assertEquals("Checks to see that we have added an element correctly",count+1,rModel.getAllOfType("CUSTOMER").size());
		rModel.deleteElement(element);	
		assertEquals("Checks to see that we have deleted an element correctly",count,rModel.getAllOfType("CUSTOMER").size());		
	} 
	catch (EolModelElementTypeNotFoundException e) 
	{
		e.printStackTrace();
	} 
	catch (EolNotInstantiableModelElementTypeException e) 
	{
		e.printStackTrace();
	} catch (EolRuntimeException e) 
	{
		e.printStackTrace();
	}
}

@Test public void DBReflexiveModelElement_deleteElement_null()
{	
	try {
		int count = rModel.getAllOfType("CUSTOMER").size();
		Object element = rModel.createInstance("CUSTOMER");
		assertEquals("Checks to see that we have added an element correctly",count+1,rModel.getAllOfType("CUSTOMER").size());
		rModel.deleteElement(null);	
		assertEquals("Checks to see that we have deleted an element correctly",count+1,rModel.getAllOfType("CUSTOMER").size());		
        fail("This should throw a null pointer Exception");	
	} 
	catch (EolModelElementTypeNotFoundException e) 
	{
		fail("This should throw a null pointer Exception");	
		e.printStackTrace();
	} 
	catch (EolNotInstantiableModelElementTypeException e) 
	{
		fail("This should throw a null pointer Exception");	
		e.printStackTrace();
	} catch (EolRuntimeException e) 
	{
		fail("This should throw a null pointer Exception");	
		e.printStackTrace();
	}
	catch (NullPointerException e)
	{
		//This should catch the error and therefore we do not need to fail the test.
	}
}
	
	@Test public void DBReflexiveModelElement_deleteElement_twice()
	{	
		try {
			int count = rModel.getAllOfType("CUSTOMER").size();
			Object element = rModel.createInstance("CUSTOMER");
			assertEquals("Checks to see that we have added an element correctly",count+1,rModel.getAllOfType("CUSTOMER").size());
			rModel.deleteElement(element);
			rModel.deleteElement(element);
			assertEquals("Checks to see that we have deleted an element correctly",count,rModel.getAllOfType("CUSTOMER").size());		
		} 
		catch (EolModelElementTypeNotFoundException e) 
		{
			fail("This should not throw an Exception");	
			e.printStackTrace();
		} 
		catch (EolNotInstantiableModelElementTypeException e) 
		{
			fail("This should not throw an Exception");				
			e.printStackTrace();
		} catch (EolRuntimeException e) 
		{
			fail("This should not throw an Exception");	
			e.printStackTrace();
		}
		catch (NullPointerException e)
		{
			fail("This should not throw an Exception");	
			e.printStackTrace();
        }
}
	
@Test 
public void DBReflexiveModel_owns()	
{
	 try {
		Object element = rModel.createInstance("CUSTOMER");
		assertEquals("The Element is owned by the Model.",true,rModel.owns((DBReflexiveModelElement) element));
	 } 
	 catch (EolModelElementTypeNotFoundException e) 
	{
		// TODO Auto-generated catch block
		e.printStackTrace();
	} 
	 catch (EolNotInstantiableModelElementTypeException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}
	
@Test public void DBReflexiveModel_owns_deletedObject()	
{
	 try {
		Object element = rModel.createInstance("CUSTOMER");
		rModel.deleteElement(element);
		assertEquals("The Element is owned by the Model.",false,rModel.owns((DBReflexiveModelElement) element));
	 } 
	 catch (EolModelElementTypeNotFoundException e) 
	{
		// TODO Auto-generated catch block
		e.printStackTrace();
	} 
	 catch (EolNotInstantiableModelElementTypeException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (EolRuntimeException e) 
	{
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}

@Test public void DBReflexiveModel_owns_nullObject()	
{
	 try {
       Object element = rModel.createInstance("Bob");
		assertEquals("The Element is owned by the Model.",true,rModel.owns(element));
	 } 
	 catch (EolModelElementTypeNotFoundException e) 
	{
		// TODO Auto-generated catch block
		e.printStackTrace();
		fail("This should not throw this exception");
	} 
	 catch (EolNotInstantiableModelElementTypeException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
		fail("This should not throw this exception");
	 } catch (EolRuntimeException e) 
	{
		// TODO Auto-generated catch block
		e.printStackTrace();
		fail("This should not throw this exception");
	}
}

@Test 
public void DBReflexiveModel_owns_NoneDBReflexiveModelElement()	
{
	
	    Object element = new DBReflexiveModel();
		assertEquals("This is a  none element and therefore should not be owned by the Model",false,rModel.owns(element));
}


@Test
public void DBReflexiveModel_isInstantialble()
{
	
	assertEquals("This should return true as there is a valid obkect with a PK in the database",true,rModel.isInstantiable("CUSTOMER"));
}


@Test
public void DBReflexiveModel_isInstantialble_Null()
{
	assertEquals("This should return false for null Objects",false,rModel.isInstantiable(null));
}

@Test
public void DBReflexiveModel_isInstantialble_ValidTableNoPK()
{	
	assertEquals("This should return true as there is a valid obkect with a PK in the database",false,rModel.isInstantiable("ORDER_ITEM"));
}




@Test 
public void DBReflexiveModel_isModelElement()	
{
	 try {
		Object element = rModel.createInstance("CUSTOMER");
		assertEquals("The Element is owned by the Model.",true,rModel.isModelElement((DBReflexiveModelElement) element));
	 } 
	 catch (EolModelElementTypeNotFoundException e) 
	{
		// TODO Auto-generated catch block
		e.printStackTrace();
	} 
	 catch (EolNotInstantiableModelElementTypeException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}
	
@Test public void DBReflexiveModel_isModelElement_deletedObject()	
{
	 try {
		Object element = rModel.createInstance("CUSTOMER");
		rModel.deleteElement(element);
		assertEquals("The Element is owned by the Model.",false,rModel.isModelElement((DBReflexiveModelElement) element));
	 } 
	 catch (EolModelElementTypeNotFoundException e) 
	{
		// TODO Auto-generated catch block
		e.printStackTrace();
	} 
	 catch (EolNotInstantiableModelElementTypeException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (EolRuntimeException e) 
	{
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}

@Test public void DBReflexiveModel_isModelElement_nullObject()	
{
	 try {
       Object element = rModel.createInstance(null);
		assertEquals("The Element is owned by the Model.",false,rModel.isModelElement(element));
	 } 
	 catch (EolModelElementTypeNotFoundException e) 
	{
		// TODO Auto-generated catch block
		e.printStackTrace();
	} 
	 catch (EolNotInstantiableModelElementTypeException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} catch (EolRuntimeException e) 
	{
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}

@Test 
public void DBReflexiveModel_isModelElement_NoneDBReflexiveModelElement()	
{
	
	    Object element = new DBReflexiveModel();
		assertEquals("This is a  none element and therefore should not be owned by the Model",false,rModel.isModelElement(element));
}


@Test public void DBReflexiveModelElement_hasType()
{
	assertEquals("There should be a type of CUSTOMER in the database",true,rModel.hasType("CUSTOMER"));		
}


@Test public void DBReflexiveModelElement_hasTypeNull()
{
	assertEquals("There should not be a type of null in the database",false,rModel.hasType(null));	
}

@Test public void DBReflexiveModelElement_hasTypeNonePK()
{
	assertEquals("There should not be a type of null in the database",false,rModel.hasType("ORDER_ITEM"));
}

@Test public void DBReflexiveModelElement_hasTypeInvalidType()
{
	assertEquals("There should not be a type of null in the database",false,rModel.hasType("Bob"));
}

@Test public void DBReflexiveModel_storeString()
{
	assertEquals("This should nor do anything and thefore should return null",false,rModel.store(""));
}

@Test public void DBReflexiveModel_storeStringnull()
{
	assertEquals("This should nor do anything and thefore should return null",false,rModel.store(null));
}

@Test
public void DBReflexiveModel_store() 
{
	assertEquals("This should nor do anything and thefore should return null",false,rModel.store());	
}

@Test
public void DBReflexiveModel_IPropetyGetter_invoke()
{
	try {
		Object element = rModel.createInstance("CUSTOMER");
		Object value = rModel.getPropertyGetter().invoke(element, "CUSTOMERID");
	    assertEquals("This should bring back one column of data only","5",value.toString()); 
	} 
	catch (EolRuntimeException e) 
	{
		// TODO Auto-generated catch block
		e.printStackTrace();
	} 
}

@Test
public void DBReflexiveModel_IPropetyGetter_invoke_NullElement()
{
	try {
		Object element = rModel.createInstance("CUSTOMER");
		Object value = rModel.getPropertyGetter().invoke(null, "CUSTOMERID");
	    assertEquals("This should bring back zero row of data only",null,value.toString()); 
	   fail("This should return a null pointer Exception");
	} 
	catch (EolRuntimeException e) 
	{
		 fail("This should return a null pointer Exception");
		e.printStackTrace();
	} 
	catch (NullPointerException e) 
	{
		 //This should fail with a null pointer Exception.
	} 
}

@Test
public void DBReflexiveModel_IPropetyGetter_invoke_ElementWithIncorrectAttribute()
{
	try {
		Object element = rModel.createInstance("CUSTOMER");
		Object value = rModel.getPropertyGetter().invoke(element, "WRONGATTRIBUTE");
	    assertEquals("This should bring back zero row of data only","",value.toString());
	} 
	catch (EolRuntimeException e) 
	{
		 fail("This show not throw an exception");
		e.printStackTrace();
	} 
	catch (NullPointerException e) 
	{
		 //This should fail with a null pointer Exception.
	}
}	
	
@Test
	public void DBReflexiveModel_IPropetyGetter_invoke_ElementWithNullAttribute()
	{
		try {
			Object element = rModel.createInstance("CUSTOMER");
			Object value = rModel.getPropertyGetter().invoke(element, null);
		    assertEquals("This should bring back zero row of data only",null,value.toString()); 
		    fail("This should return a null pointer Exception");
		} 
		catch (EolRuntimeException e) 
		{
			 fail("This should return a null pointer Exception");
			e.printStackTrace();
		} 
		catch (NullPointerException e) 
		{
			 //This should fail with a null pointer Exception.
		} 
}

@Ignore
public void DBReflexiveModel_IPropetySetter_invoke()
{
try {
	
		Object element = rModel.createInstance("CUSTOMER");
		assertEquals("This should bring back null",null,rModel.getPropertyGetter().invoke(element, "FORENAME")); 
	    //rModel.getPropertySetter().setObject(element);  //This doesnt seem to set the props for this????
	    //rModel.getPropertySetter().setProperty("TEST");	
		//rModel.getPropertySetter().invoke("TestValue");
		assertEquals("This should bring back a value","TestForename",rModel.getPropertyGetter().invoke(element, "FORENAME"));
	} 
	catch (EolRuntimeException e) 
	{
		 fail("A Runtime Exception has occured");
		e.printStackTrace();
	} 
	catch (NullPointerException e) 
	{
		 fail("This returns a null pointer Exception");
		 //This should fail with a null pointer Exception.
	} 
}































}